/* Copyright - Apache License 2.0
 * 
 * The project "kyou" is
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *      http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.kyou.data.dquery;

import net.kyou.data.SchemaItem;

/**
 * 复杂的DQuery，包含各种复杂的匹配逻辑
 * 
 * @author NuclearG (<a href="mailto:nuclearg@163.com">nuclearg@163.com</a>)
 */
class ComplexDQuery extends DQuery {
    /**
     * 该DQuery的各个段
     */
    private final DQuerySegment[] segments;

    ComplexDQuery(DQuerySegment[] segments) {
        this.segments = segments;
    }

    @Override
    public boolean matches(String path, SchemaItem schema) {
        // 将报文路径分成段，将这些段与DQuery段进行段与段之间的匹配
        int pathSegmentId = 0;
        String[] pathSegments = path.split("\\.");

        for (int i = 0; i < this.segments.length; i++)
            switch (this.matchSegment(this.segments[i], pathSegments, pathSegmentId)) {
                case OK:
                    // 段间匹配成功，尝试使用下一个报文段和DQuery段进行匹配
                    pathSegmentId++;
                    continue;
                case TryNext:
                    // 当前段匹配失败，尝试使用下一个报文段进行匹配
                    i--;
                    pathSegmentId++;
                    break;
                case Fail:
                    // 段间匹配失败 此时不需要进行后续匹配，直接报告匹配失败
                    return false;
            }

        return true;
    }

    /**
     * 工具函数 进行报文路径与DQuery段之间段与段的匹配
     */
    private MatchResult matchSegment(DQuerySegment segment, String[] pathSegments, int pathSegmentId) {
        if (pathSegmentId > pathSegments.length)
            return MatchResult.Fail;

        return MatchResult.Fail;
    }

    /**
     * 对单个段进行验证时的结论
     * 
     * @author NuclearG (<a href="mailto:nuclearg@163.com">nuclearg@163.com</a>)
     */
    private enum MatchResult {
        /**
         * 匹配成功
         */
        OK,
        /**
         * 匹配失败，尝试使用报文路径的下一段进行匹配
         */
        TryNext,
        /**
         * 匹配失败，且不可恢复
         */
        Fail
    }
}
